package com.power.sifa.approve.executor.impl;

import com.alibaba.fastjson.JSON;
import com.aventrix.jnanoid.jnanoid.NanoIdUtils;
import com.plf.common.domain.ResponseDTO;
import com.plf.common.domain.YesNo;
import com.power.flowable.api.IPersonalFeign;
import com.power.sifa.util.executor.AbstractPostExecutor;
import com.power.sifa.approve.model.Apl_admre_audit;
import com.power.sifa.approve.model.Apl_admreview;
import com.power.sifa.approve.model.Apl_main;
import com.power.sifa.approve.model.enumeration.St_admreview;
import com.power.sifa.approve.model.enumeration.St_apply;
import com.power.sifa.approve.model.enumeration.Tp_proctype;
import com.power.sifa.approve.model.pojo.vo.ProcessVariablesVo;
import com.power.sifa.approve.service.*;
import com.power.sifa.approve.thread.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 调解完成服务
 */
@Component
@Slf4j
public class HearAuditMediate extends AbstractPostExecutor {

    // 用户id
    private String userid;
    // 环节分类标识
    private String category;
    // 用户名
    private String username;
    // 单位id
    private String sectionid;
    // 单位名称
    private String sectionname;
    // 部门id
    private String deptid;
    // 部门名称
    private String deptname;
    // 处理意见
    private String remark;
    // 行政区划
    private String adid;
    // 环节名称
    private String taskname;

    @Resource
    private Apl_admreviewService apl_admreviewService;
    @Resource
    private BusinessApproveService businessApproveService;
    @Resource
    private Apl_mainService apl_mainService;
    @Resource
    private IPersonalFeign iPersonalFeign;
    @Resource
    private Apl_dossierService apl_dossierService;
    @Resource
    private Apl_archiveService apl_archiveService;
    @Resource
    private Apl_admre_auditService apl_admre_auditService;

    @Override
    public void init(Map<String, Object> initdata) {
        this.userid = (String) initdata.get("userid");
        this.category = (String) initdata.get("category");
        this.username = (String) initdata.get("username");
        this.sectionid = (String) initdata.get("sectionid");
        this.sectionname = (String) initdata.get("sectionname");
        this.deptid = (String) initdata.get("deptid");
        this.deptname = (String) initdata.get("deptname");
        this.remark = (String) initdata.get("remark");
        this.adid = (String) initdata.get("adid");
        this.taskname = (String) initdata.get("taskname");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> execute() throws Exception {
        // 1. 生成和保存三级审批文书
        Apl_admre_audit auditObj = this.apl_admre_auditService.getById(super.applyid);
        Apl_main mainObj = this.apl_mainService.getById(super.applyid);
        Apl_main faMainObj = this.apl_mainService.getById(auditObj.getApplyid());

        // 2.1  如果需要市领导审批, 不自动生成审批表
        if(YesNo.NO == auditObj.getIssecondout()) {
            // 2. 生成审批表
            this.businessApproveService.createThreeLevelApprove(super.applyid, this.userid, this.username, Tp_proctype.HEAR_MEDIATE);
            // 3.1  启动一个结果审批流程 (不管要不要市领导审批都需要一个结果审批流程)
            Apl_admreview admreObj = this.apl_admreviewService.getById(auditObj.getApplyid());
            Apl_main newMainObj = JSON.parseObject(JSON.toJSONString(mainObj), Apl_main.class);
            Date now = new Date();
            newMainObj.setId(now.getTime() +  NanoIdUtils.randomNanoId());
            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now);
            newMainObj.setCreatetime(date);
            newMainObj.setCreatetime(date);
            String soninstid = this.businessApproveService.createSonProcess(faMainObj, newMainObj, admreObj, this.userid, "", St_admreview.ACCEPT, Tp_proctype.HEAR_MEDIATE, auditObj.getIscitymanager(), YesNo.YES);
            // 记录流程变量
            Map<String, Object> variableMap = new HashMap<>(16);
            variableMap.put(ProcessVariablesVo.CITYAPPROVE, auditObj.getIssecondout());
            ResponseDTO res = this.iPersonalFeign.saveVariable(soninstid, variableMap);
            if(0 != res.getCode()) {
                throw new RuntimeException(res.getMsg());
            }
            return null;
        }

        // 2. 通过即结束
        // 2.1 清空所有子状态
        Apl_admreview admreObj = this.apl_admreviewService.getById(faMainObj.getId());
        this.apl_admreviewService.updatesSonStatus(admreObj.getId(), null);
        this.apl_admreviewService.updateStatus(admreObj.getId(), St_admreview.MEDIATE);

        // 2.2 关闭所有在办子流程
        ResponseDTO res = this.iPersonalFeign.terminationSonProcess(faMainObj.getInstid(), mainObj.getInstid(), this.userid, "申请已调解，故中途办结");
        if (0 != res.getCode()) {
            log.error("HearAuditMediate 关闭所有在办子流程失败 ->  msg[{}]", res.getMsg());
            throw new RuntimeException("关闭所有在办子流程失败");
        }

        // 3. 获取需要修改业务状态的实例id
        List<String> instids = (List<String>) res.getData();
        if (!CollectionUtils.isEmpty(instids)) {
            this.apl_mainService.updateStatusByInstid(St_apply.FINISH, instids);
        }

        // 5先激活 (没挂起就拿一个taskid)
        ResponseDTO activeRes = this.iPersonalFeign.activationProcess(faMainObj.getInstid());
        if(0 != activeRes.getCode()) {
            log.error("HearAuditMediate 激活父流程失败 -> msg[{}]", activeRes.getMsg());
            throw new RuntimeException("HearAuditMediate 激活父流程失败 -> " + activeRes.getMsg());
        }
        // 5.1 父流程自动走一步
        String taskid = (String) activeRes.getData(); // 父流程任务id
        ThreadPoolUtil.executor.execute(() -> {
            ResponseDTO axecRes =  this.iPersonalFeign.processNext(faMainObj.getFormid(), faMainObj.getId(), taskid, userid, new HashMap());
            if(0 != axecRes.getCode()) {
                log.error("HearAuditMediate 完成父流程任务失败 -> msg[{}]", axecRes.getMsg());
                throw new RuntimeException("HearAuditMediate 完成父流程任务失败");
            }
        });

        // 6. 初始归档数据
        ThreadPoolUtil.executor.execute(() -> {
            // 6.1 初始化归档首页数据
            this.apl_archiveService.initialArchiveData(faMainObj.getId());
            // 6.2 初始化归档电子卷宗数据
            this.apl_dossierService.buildInitDossier(faMainObj.getId());
        });

        // 刷新文书日期
        this.businessApproveService.processEndedUpdatePreviewDoc(auditObj.getApplyid(), Tp_proctype.HEAR_MEDIATE, null);
        // 文书盖章
        this.businessApproveService.templateStamp(auditObj.getApplyid(), Tp_proctype.HEAR_MEDIATE);
        return null;
    }

}
